HardwareSerial Aizk(2);
const int serial2BaudRate = 9600;
// 定义Serial1的发送引脚为10
const int serial2RxPin = 15;
// 定义Serial1的接收引脚为11
const int serial2TxPin = 4;

bool aizkStatus = false;

int switchArray[8] = {0};

long aizkDataPreTick = 0;

// 存储接收到的数据
std::vector<uint8_t> azkBuffer;

// 校验函数
bool calculateChecksum(const std::vector<uint8_t> &data)
{
    uint8_t checksum = 0;
    for (int i = 0; i < data.size() - 1; i++)
    {
        checksum += data[i];
    }
    checksum &= 0xFF;
    if (checksum != data.back())
    {
        // 计算提取数据的校验和
        sendtoData("azk校验失败!");
        String dataString = "原数据 : ";
        for (uint8_t dataByte : azkBuffer)
        {
            dataString += String(dataByte, HEX) + " ";
        }
        sendtoData(dataString);
        delay(2000);
        dataString = "校验数据 : ";
        for (uint8_t dataByte : data)
        {
            dataString += String(dataByte, HEX) + " ";
        }
        sendtoData(dataString);
    }
    return checksum == data.back();
}
bool processData(const std::vector<uint8_t> &data)
{
    if (data.size() >= 5 && calculateChecksum(data))
    {
        aizkStatus = true;
        // 在这里进行数据校验操作，校验通过后处理数据
        if (data[1] == 0x03)
        {
            for (size_t i = 0; i < 8; i++)
            {
                config.switchArray[i] = data[3] >> i & 1;
            }
        }
        else if (data[1] == 0x07)
        {
            for (size_t i = 0; i < 8; i++)
            {
                config.switchArray[i] = data[3] >> i & 1;
            }
            // dcVoltage = (data[20] << 8 | data[21]) / 100.0;
            // dcCurrent = (data[22] << 8 | data[23]) / 100.0;
            // dcPower = (data[24] << 8 | data[25]) / 10.0;
            // dcEnergy = (data[26] << 8 | data[27]) / 1000.0;
            // sendtoData(String(dcVoltage));
            // sendtoData(String(dcCurrent));
            // sendtoData(String(dcPower));
            // sendtoData(String(dcEnergy));
        }
        for (size_t i = 0; i < 8; i++)
        {
            if (switchArray[i] != config.switchArray[i])
            {
                for (size_t j = 0; j < 8; j++)
                {
                    switchArray[j] = config.switchArray[j];
                }
                // sendtoData("开关保存");
                saveConfig();
                break;
            }
        }
    }
    else
    {
        for (uint8_t dataByte : data)
        {
            Serial.print(dataByte, HEX);
            Serial.print(' ');
        }
        Serial.println();
        return false;
    }
    return true;
}

// 查找数据头函数，返回找到的数据头索引，没找到返回std::string::npos
size_t azkFindHeader(const std::vector<uint8_t> &buffer, size_t startIndex = 0)
{
    const uint8_t syncHeader0 = 0xFF; // 同步头
    const uint8_t syncHeader3 = 0x03; // 开关状态
    const uint8_t syncHeader7 = 0x07; // 所以数据
    const uint8_t syncHeader9 = 0x09; // 反馈数据
    const uint8_t syncHeader1 = 0x01; // 反馈数据
    const uint8_t syncHeader4 = 0x04; // 反馈数据
    const uint8_t syncHeader6 = 0x06; // 反馈数据
    const uint8_t syncHeader8 = 0x08; // 反馈数据

    for (size_t i = startIndex; i < buffer.size(); ++i)
    {
        if (buffer[i] == syncHeader0 && (buffer[i + 1] == syncHeader3 || buffer[i + 1] == syncHeader7 || buffer[i + 1] == syncHeader9))
        {
            return i;
        }
        // else if (buffer[i] == syncHeader1 && buffer[i + 1] == syncHeader4 && buffer[i + 5] == syncHeader6 && buffer[i + 7] == syncHeader8)
        // {
        //     azkBuffer.erase(azkBuffer.begin() + i, azkBuffer.begin() + i + 7);
        //     return i;
        // }
        if (buffer[i] == syncHeader1 && buffer[i + 1] == syncHeader4)
        {
            return i;
        }
    }
    return std::string::npos;
}

void receiveData()
{
    // 读取串口数据并存储到缓冲区中
    if (Aizk.available() > 0)
    {
        int uint8Size = Aizk.available();
        uint8_t uint8[uint8Size];
        Aizk.readBytes(uint8, uint8Size);
        azkBuffer.insert(azkBuffer.end(), uint8, uint8 + uint8Size);
        // for (uint8_t dataByte : azkBuffer)
        // {
        //     Serial.print(dataByte, HEX);
        //     Serial.print(' ');
        // }
        // Serial.println();
    }
}
// 提取正确的数据
void SensorData()
{
    size_t prevHeaderIndex = std::string::npos;
    size_t currentHeaderIndex = std::string::npos;
    int size = 0;
    if (azkBuffer.size() >= 5)
    {
        // String dataString = "数据 : ";
        // for (uint8_t dataByte : azkBuffer)
        // {
        //     dataString += String(dataByte, HEX) + " ";
        // }
        // sendtoData(dataString);

        // 查找当前数据头
        currentHeaderIndex = azkFindHeader(azkBuffer);

        if (currentHeaderIndex != std::string::npos)
        { // 查找当前数据头
            prevHeaderIndex = azkFindHeader(azkBuffer, currentHeaderIndex + 3);

            if ((azkBuffer.size() == 5 && azkBuffer[1] == 0x09) || (azkBuffer.size() == 54 && azkBuffer[1] == 0x07) || (azkBuffer.size() == 17 && azkBuffer[1] == 0x04))
            {
                if (processData(azkBuffer))
                {
                    SensorData(azkBuffer);
                }
                azkBuffer.clear();
            }
            else if (prevHeaderIndex != std::string::npos)
            {
                // 提取两个数据头之间的数据
                std::vector<uint8_t> extractedData(azkBuffer.begin() + currentHeaderIndex, azkBuffer.begin() + prevHeaderIndex);
                if (processData(extractedData))
                {
                    SensorData(extractedData);
                }
                azkBuffer.erase(azkBuffer.begin(), azkBuffer.begin() + prevHeaderIndex);
            }
        }
    }
}
// 发送读取数据命令
void sendCommand()
{
    uint8_t sendData[] = {0xFF, 0x06, 0x01, 0x55, 0x5B};
    // uint8_t sendData[] = {0XFF, 0X04, 0X01, 0X00, 0X04};
    Aizk.write(sendData, sizeof(sendData));
}

// 根据指令改变开关状态并发送对应指令函数
void changeSwitchStatusAndSendCommand(String instruction)
{
    // K1 相关操作
    if (instruction.startsWith("K1_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x00, 0xFF, 0x0A};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K1_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x00, 0x00, 0x0B};
        Aizk.write(command, sizeof(command));
    }
    // K2 相关操作
    else if (instruction.startsWith("K2_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x01, 0xFF, 0x0B};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K2_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x01, 0x00, 0x0C};
        Aizk.write(command, sizeof(command));
    }
    // K3 相关操作
    else if (instruction.startsWith("K3_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x02, 0xFF, 0x0C};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K3_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x02, 0x00, 0x0D};
        Aizk.write(command, sizeof(command));
    }
    // K4 相关操作
    else if (instruction.startsWith("K4_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x03, 0xFF, 0x0D};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K4_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x03, 0x00, 0x0E};
        Aizk.write(command, sizeof(command));
    }
    // K5 相关操作
    else if (instruction.startsWith("K5_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x04, 0xFF, 0x0E};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K5_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x04, 0x00, 0x0F};
        Aizk.write(command, sizeof(command));
    }
    // K6 相关操作
    else if (instruction.startsWith("K6_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x05, 0xFF, 0x0F};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K6_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x05, 0x00, 0x10};
        Aizk.write(command, sizeof(command));
    }
    // K7 相关操作
    else if (instruction.startsWith("K7_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x06, 0xFF, 0x10};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K7_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x06, 0x00, 0x11};
        Aizk.write(command, sizeof(command));
    }
    // K8 相关操作
    else if (instruction.startsWith("K8_on"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x07, 0xFF, 0x11};
        Aizk.write(command, sizeof(command));
    }
    else if (instruction.startsWith("K8_off"))
    {
        uint8_t command[] = {0xFF, 0x0A, 0x02, 0x07, 0x00, 0x12};
        Aizk.write(command, sizeof(command));
    }
    aizkDataPreTick = millis();
}

// 发送数据函数，一次性处理5个变量
void sendDataThroughSerial(uint8_t byte, float var1, float var2, float var3, float var4, float var5)
{
    // 创建一个数组用于存储要发送的数据字节，根据实际数据量调整大小
    uint8_t sendBuffer[20];
    int bufferIndex = 0;

    sendBuffer[bufferIndex++] = 0xFF;
    sendBuffer[bufferIndex++] = 0x08;
    sendBuffer[bufferIndex++] = 0x0B;
    sendBuffer[bufferIndex++] = byte;

    int intVar1 = abs(var1 * 100);
    sendBuffer[bufferIndex++] = (intVar1 >> 8) & 0xFF;
    sendBuffer[bufferIndex++] = intVar1 & 0xFF;

    int intVar2 = abs(var2 * 100);
    sendBuffer[bufferIndex++] = (intVar2 >> 8) & 0xFF;
    sendBuffer[bufferIndex++] = intVar2 & 0xFF;

    int intVar3 = abs(var3 * 100);
    sendBuffer[bufferIndex++] = (intVar3 >> 8) & 0xFF;
    sendBuffer[bufferIndex++] = intVar3 & 0xFF;

    int intVar4 = abs(var4 * 100);
    sendBuffer[bufferIndex++] = (intVar4 >> 8) & 0xFF;
    sendBuffer[bufferIndex++] = intVar4 & 0xFF;

    int intVar5 = abs(var5 * 100);
    sendBuffer[bufferIndex++] = (intVar5 >> 8) & 0xFF;
    sendBuffer[bufferIndex++] = intVar5 & 0xFF;

    // 简单计算校验和（累加和取低8位）
    uint8_t checksum = 0;
    for (int i = 0; i < bufferIndex; i++)
    {
        checksum += sendBuffer[i];
    }
    checksum &= 0xFF;
    sendBuffer[bufferIndex++] = checksum;

    // 通过串口发送数据
    Aizk.write(sendBuffer, bufferIndex);
}

// 串口初始化函数，用于设置Serial1串口的参数，使其能够正常进行数据通信
void setupAizk()
{
    // 初始化Serial1串口，设置波特率为serial1BaudRate（9600），数据位8位，无校验位，停止位1位，
    // 并指定发送引脚为serial1TxPin（10），接收引脚为serial1RxPin（11）
    Aizk.begin(serial2BaudRate, SERIAL_8N1, serial2TxPin, serial2RxPin);
}

void loopAizk()
{
    static int Aizk = 0;
    static long receiveDataTick = 0;

    if (millis() - aizkDataPreTick >= 500)
    {
        if (Aizk == 0)
        {
            Aizk++;
            sendCommand();
        }
        else if (Aizk == 1)
        {
            Aizk++;
            receiveData();
            sendDataThroughSerial(0x00, batteryVoltage, batteryCurrent, batteryPower, batteryTemperature, int(batteryCharge));
        }
        else if (Aizk == 2)
        {
            Aizk++;
            sendDataThroughSerial(0x01, chargeVoltage, chargeCurrent, pvVoltage, pvCurrent, pvPower);
        }
        else if (Aizk == 3)
        {
            Aizk = 0;
            sendDataThroughSerial(0x02, gridPower, gridEfficiency, usagePower, usageCurrent, usagePowerFactor);
        }

        aizkDataPreTick = millis();
    }
    if (millis() - receiveDataTick >= 100)
    {
        receiveData();
        SensorData();
        receiveDataTick = millis();
    }
}